import os
import allure
from selenium import webdriver
from common.logger import logger
from selenium.webdriver.common.action_chains import ActionChains


class BasePage:
    def __init__(self, driver):
        """
        :param driver: driver对象
        """
        self.driver = driver

    def quit_browser(self):
        """
        关闭浏览器及后台相关进程
        """
        self.driver.quit()

    def find_element(self, selector_by, attribute):
        """
        通过多种定位方式,提供定位元素;支持定位方式简写
        :param selector_by: 定位方式
        :param attribute: 定位对象
        :return: element
        """
        element = ''
        if selector_by == 'id' or selector_by == 'i':
            try:
                element = self.driver.find_element_by_id(attribute)
            except Exception as e:
                logger().error(e)
        elif selector_by == 'name' or selector_by == 'n':
            try:
                element = self.driver.find_element_by_name(attribute)
            except Exception as e:
                logger().error(e)
        elif selector_by == 'class' or selector_by == 'c':
            try:
                element = self.driver.find_element_by_name(attribute)
            except Exception as e:
                logger().error(e)
        elif selector_by == 'xpath' or selector_by == 'x':
            try:
                element = self.driver.find_element_by_xpath(attribute)
            except Exception as e:
                logger().error(e)
        else:
            logger().warning('定位方式不存在,请联系相关人员进行代码重构')
        return element

    def click(self, selector_by, attribute):
        """
        点击
        :param selector_by:
        :param attribute:
        """
        try:
            self.find_element(selector_by, attribute).click()
        except Exception as e:
            logger().error(e)

    def send_contents(self, selector_by, attribute, contents):
        """
        填写内容
        :param selector_by:
        :param attribute:
        :param contents: 填写的内容
        """
        try:
            self.find_element(selector_by, attribute).send_keys(contents)
        except Exception as e:
            logger().error(e)

    def screenshot(self, img_name):
        """
        截图
        :param img_name:图片名
        """
        current_path = os.path.abspath(os.path.dirname(os.getcwd()))  # 获取当前路径
        is_exists = os.path.exists(r'{}\picture'.format(current_path))  # 判断当前路径父级有没有report文件夹
        if not is_exists:
            os.makedirs(r'{}\picture'.format(current_path))
        self.driver.get_screenshot_as_file(r'{}\picture\{}.png'.format(current_path, img_name))
        return current_path

    def all_contents(self):
        """
        源码
        :return:
        """
        return self.driver.page_source

    def get_text(self, selector_by, attribute):
        return self.find_element(selector_by, attribute).text

    def back(self):
        self.driver.back()

    def clear(self, selector_by, attribute):
        self.find_element(selector_by, attribute).clear()

    def assert_exception(self, tester, verifyer, img_name):
        """
        自定义assert.如果断言错误,会保存当前界面图片并集成到allure中去
        :param tester: 测试对象
        :param verifyer: 验证对象
        :param img_name: 如果发生异常生成的图片
        :return:
        """
        if tester in verifyer:
            return True
        elif tester == verifyer:
            return True
        else:
            current_path = self.screenshot(img_name)  # 截图
            allure.attach.file(r'{}\picture\{}.png'.format(current_path, img_name),
                               attachment_type=allure.attachment_type.PNG)  # 将截图放到allure报告中
            raise AssertionError("tester and verifyer is not correct ")

    def mouse_over(self, selector_by, attribute):
        """
        鼠标移动到某处
        :param selector_by:
        :param attribute:
        :return:
        """
        place = self.find_element(selector_by, attribute)
        ActionChains(self.driver).move_to_element(place).perform()

    def mouse_over_click(self, selector_by, attribute):
        """
        鼠标移动到某处点击
        :param selector_by:
        :param attribute:
        :return:
        """
        place = self.find_element(selector_by, attribute)
        ActionChains(self.driver).click(place).perform()

    def execute_script(self, js):
        self.driver.execute_script(js)


if __name__ == '__main__':
    driver = webdriver.Chrome()
    driver.get('https://www.baidu.com')
    m = BasePage(driver)
    m.mouse_over('x', '//div[@id="u1"]/a[8]')
    m.mouse_over_click('x', '//*[@id="wrapper"]/div[6]/a[4]')
    m.quit_browser()
